package qc.module.duty.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.common.core.unify.QCUnifyReturnValue;
import qc.module.duty.dto.group.DutyGroupDto;
import qc.module.duty.entity.DutyGroup;
import qc.module.duty.entity.DutySchedule;
import qc.module.duty.mapper.DutyGroupMapper;
import qc.module.duty.repository.DutyGroupRepository;
import qc.module.duty.repository.DutyScheduleRepository;

import java.util.List;
import java.util.Map;

@Service
public class DutyGroupService {
    private DutyGroupRepository repository;

    @Autowired
    public void setRepository(DutyGroupRepository repository) {
        this.repository = repository;
    }

    private DutyScheduleRepository scheduleRepository;

    @Autowired
    public void setDutyScheduleRepository(DutyScheduleRepository scheduleRepository) {
        this.scheduleRepository = scheduleRepository;
    }

    /***
     * 查询值班分组
     *
     * @param filterDeptIds 过滤的部门ID集合，只查询在此结合中的部门值班分组；如果集合为空，查询结果为空
     * @param deptIdAndNames 返回结果中需要有部门名称信息，在此传入部门ID和名称对应关系
     * @return java.util.List<qc.module.duty.dto.group.DutyGroupDto>
     * @author QuCheng Tech
     * @since 2023/8/11
     */
    public List<DutyGroupDto> query(List<Integer> filterDeptIds, Map<Integer, String> deptIdAndNames) {
        if (filterDeptIds != null && filterDeptIds.size() > 0x0) {
            LambdaQueryWrapper<DutyGroup> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(DutyGroup::getDept, filterDeptIds);

            // 按照 DutyGroup 的 odr 字段进行升序排序
            wrapper.orderByAsc(DutyGroup::getOdr);

            List<DutyGroup> dutyGroups = repository.selectList(wrapper);

            if (dutyGroups != null && dutyGroups.size() > 0x0) {
                // 将 DutyGroup 列表映射为 DutyGroupDto 列表
                List<DutyGroupDto> result = DutyGroupMapper.MAPPER.toDtoList(dutyGroups);

                // 遍历 DutyGroupDto 列表，为每个 DutyGroupDto 设置部门名称
                if (deptIdAndNames != null && deptIdAndNames.size() > 0x0) {
                    for (DutyGroupDto dutyGroupDto : result) {
                        Integer deptId = dutyGroupDto.getDeptid();
                        if (deptIdAndNames.containsKey(deptId))
                            dutyGroupDto.setDeptname(deptIdAndNames.get(deptId));
                    }
                }

                return result;
            }
        }

        return null;
    }

    /**
     * 获取指定值班组
     *
     * @param id: 值班组id
     * @return DutyGroupDto
     * @author QcCheng Tech
     * @date 2023/8/9
     */
    public DutyGroupDto get(int id) {
        // 使用 dutyGroupRepository 根据 ID 查询 DutyGroup 对象
        DutyGroup dutyGroup = repository.selectById(id);
        // 如果查询结果为空，则返回空
        if (dutyGroup != null)
            // 将 DutyGroup 对象映射为 DutyGroupDto 对象
            return DutyGroupMapper.MAPPER.EntityToDutyGroupDto(dutyGroup);
        return null;
    }

    /*根据值班组ID集合查询值班分组信息*/
    public List<DutyGroupDto> queryGroupDtoList(List<Integer> groupids, Map<Integer, String> deptIdAndNames) {
        LambdaQueryWrapper<DutyGroup> wrapper = new LambdaQueryWrapper();
        wrapper.in(DutyGroup::getId, groupids);
        // 按照 DutyGroup 的 odr 字段进行升序排序
        wrapper.orderByAsc(DutyGroup::getOdr);
        List<DutyGroup> dutyGroups = repository.selectList(wrapper);
        if (dutyGroups != null && dutyGroups.size() > 0x0) {
            // 将 DutyGroup 列表映射为 DutyGroupDto 列表
            List<DutyGroupDto> result = DutyGroupMapper.MAPPER.toDtoList(dutyGroups);

            // 遍历 DutyGroupDto 列表，为每个 DutyGroupDto 设置部门名称
            if (deptIdAndNames != null && deptIdAndNames.size() > 0x0) {
                for (DutyGroupDto dutyGroupDto : result) {
                    Integer deptId = dutyGroupDto.getDeptid();
                    if (deptIdAndNames.containsKey(deptId))
                        dutyGroupDto.setDeptname(deptIdAndNames.get(deptId));
                }
            }

            return result;
        }
        return null;
    }

    /**
     * 添加值班组
     *
     * @param dto:对象
     * @return String 添加成功返回null,错误返回错误信息
     * @author QcCheng Tech
     * @date 2023/8/9
     */
    public String add(DutyGroupDto dto) {
        if (dto == null)
            return QCUnifyReturnValue.Warn("对象不能为空");
        if (StringUtils.isBlank(dto.getName()))
            return QCUnifyReturnValue.Warn("称值班组名不能为空");
        //判断名称不能重复
        if (isNameHasExist(dto.getName(), 0x0))
            return QCUnifyReturnValue.Warn("称值班组名已存在，名称不能相同");
        //DTO转换为Entity
        DutyGroup dutyGroup = DutyGroupMapper.MAPPER.DutyGroupDtoToEntity(dto);
        //自动生成栏目ID，获取数据库中的最大id+1后赋值
        dutyGroup.setId(genereateId());

        if (repository.insert(dutyGroup) < 0x1)
            return QCUnifyReturnValue.Warn("保存失败");
        return QCUnifyReturnValue.Success();
    }

    /**
     * 修改值班组
     *
     * @param dto 值班组信息
     * @return 成功返回null
     * @author QuCheng Tech
     * @date 2023/8/9
     */
    public String update(DutyGroupDto dto) {
        if (dto == null)
            return QCUnifyReturnValue.Warn("对象不能为空");
        if (StringUtils.isBlank(dto.getName()))
            return QCUnifyReturnValue.Warn("值班分组名称不能为空");
        if (dto.getDeptid() < 0x1)
            return QCUnifyReturnValue.Warn("所属部门ID不能为空");
        //DTO转换为Entity
        DutyGroup dutyGroup = DutyGroupMapper.MAPPER.DutyGroupDtoToEntity(dto);
        //判断名称不能重复
        if (isNameHasExist(dto.getName(), dutyGroup.getId()))
            return QCUnifyReturnValue.Warn("值班分组名称已存在，名称不能相同");

        if (!hasIdExist(dto.getId())) {
            return QCUnifyReturnValue.Warn("修改id不存在");
        }

        repository.updateById(dutyGroup);

        return QCUnifyReturnValue.Success();
    }

    /**
     * 删除值班组
     *
     * @param groupId: 值班组id
     * @return String 成功返回null，失败返回错误信息
     * @author QcCheng Tech
     * @date 2023/8/9
     */
    public String delete(int groupId) {
        if (hasGroupInSchedule(groupId))
            return QCUnifyReturnValue.Warn("当前值班分组已在排班记录中存在，删除后会导致排班信息无法正常显示，无法进行删除操作");

        repository.deleteById(groupId);

        return QCUnifyReturnValue.Success();
    }

    /**
     * @param name 名称
     * @param id   ID，新增时设置ID为0，修改时设置ID为记录ID
     * @return true表示名称已存在，false表示名称不存在
     * @author QuCheng Tech
     * @since 2023/5/25
     */
    boolean isNameHasExist(String name, Integer id) {
        //验证名称是否重复条件：name=name and id<>id
        LambdaQueryWrapper<DutyGroup> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DutyGroup::getName, name);
        wrapper.ne(DutyGroup::getId, id);
        DutyGroup en = repository.selectOne(wrapper);
        if (en != null)
            return true;

        return false;
    }

    /**
     * 判断指定的ID是否存在
     *
     * @param id 栏目ID
     * @return true表示已存在，false表示不存在
     * @author QuCheng Tech
     * @since 2023/5/26
     */
    public boolean hasIdExist(Integer id) {
        LambdaQueryWrapper<DutyGroup> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DutyGroup::getId, id);

        DutyGroup en = repository.selectOne(wrapper);
        if (en != null)
            return true;

        return false;
    }

    /**
     * 生成记录ID，获取数据库表中的最大记录ID+1
     *
     * @return 生成记录ID
     * @author QuCheng Tech
     * @since 2023/5/25
     */
    Integer genereateId() {
        Integer maxRecordId = getMaxId();
        return maxRecordId + 1;
    }

    /**
     * 获取数据库表中的最大ID值，没有记录时返回0
     *
     * @return 返回数据库表中的最大ID值
     * @author QuCheng Tech
     * @since 2023/5/25
     */
    Integer getMaxId() {
        LambdaQueryWrapper<DutyGroup> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(DutyGroup::getId);
        wrapper.orderByDesc(DutyGroup::getId);
        DutyGroup en = repository.selectOne(wrapper);
        if (en != null)
            return en.getId();

        return 0x0;
    }

    /***
     * 判断指定的值班分组ID是否已在排班表中存在
     *
     * @param groupId 值班分组ID
     * @return boolean
     * @author QuCheng Tech
     * @since 2023/9/6
     */
    boolean hasGroupInSchedule(int groupId) {
        LambdaQueryWrapper<DutySchedule> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(DutySchedule::getId);
        wrapper.eq(DutySchedule::getGid, groupId);

        DutySchedule en = scheduleRepository.selectOne(wrapper);
        if (en != null)
            return true;

        return false;
    }
}
